////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
//  File name:   VoxelObjectpanel.cpp
//  Version:     v1.00
//  Created:     2/12/2002 by Sergiy Shaykin.
//  Compilers:   Visual Studio.NET
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "VoxelObjectPanel.h"
#include "Objects\VoxelObject.h"
#include "SegmentedWorld/SegmentedWorldManager.h"

// CVoxelObjectPanel dialog

IMPLEMENT_DYNAMIC(CVoxelObjectPanel, CXTResizeDialog)
CVoxelObjectPanel::CVoxelObjectPanel(CWnd* pParent /*=NULL*/)
	: CXTResizeDialog(CVoxelObjectPanel::IDD, pParent)
{
	m_voxelObj = 0;
	Create( IDD,pParent );
}

//////////////////////////////////////////////////////////////////////////
CVoxelObjectPanel::~CVoxelObjectPanel()
{
}

//////////////////////////////////////////////////////////////////////////
void CVoxelObjectPanel::DoDataExchange(CDataExchange* pDX)
{
	CXTResizeDialog::DoDataExchange(pDX);
	//DDX_Control(pDX, IDC_SAVE_TO_CGF, m_btn1);
	//DDX_Control(pDX, IDC_REFRESH, m_btn2);
	//DDX_Control(pDX, IDC_SIDES, m_sides);
	//DDX_Control(pDX, IDC_GEOMETRY_EDIT, m_subObjEdit);
}

//////////////////////////////////////////////////////////////////////////
void CVoxelObjectPanel::SetVoxelObject( CVoxelObject *obj )
{
	m_voxelObj = obj;
}

BEGIN_MESSAGE_MAP(CVoxelObjectPanel, CXTResizeDialog)
	//ON_CBN_SELENDOK(IDC_SIDES, OnCbnSelendokSides)
	//ON_BN_CLICKED(IDC_SAVE_TO_CGF, OnBnClickedSavetoCGF)
	ON_BN_CLICKED(IDC_VOXEL_RESET_XFORM, OnBnClicked)
	ON_BN_CLICKED(IDC_VOXEL_SPLIT, OnBnSplit)
	ON_BN_CLICKED(IDC_VOXEL_UPDATE, OnUpdate)
	ON_BN_CLICKED(IDC_VOXEL_SELECT_EMPTY, OnSelectEmpty)
	ON_BN_CLICKED(IDC_VOXEL_COPYHM, OnCopyHM)
	ON_BN_CLICKED(IDC_VOXEL_HOLE, OnTerrainHole)
	
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////////////////
void CVoxelObjectPanel::SetEnable( bool bEnable)
{
	GetDlgItem(IDC_VOXEL_RESET_XFORM)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_SPLIT)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_UPDATE)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_SELECT_EMPTY)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_COPYHM)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_HOLE)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_MOVE)->EnableWindow(bEnable);
}

//////////////////////////////////////////////////////////////////////////
void CVoxelObjectPanel::SetEnableMultiSel(bool bEnable, bool bAllOfSameType)
{
	GetDlgItem(IDC_VOXEL_RESET_XFORM)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_SPLIT)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_UPDATE)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_SELECT_EMPTY)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_COPYHM)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_HOLE)->EnableWindow(bEnable);
	GetDlgItem(IDC_VOXEL_MOVE)->EnableWindow(bEnable);
}

//////////////////////////////////////////////////////////////////////////
BOOL CVoxelObjectPanel::OnInitDialog()
{
	CXTResizeDialog::OnInitDialog();

	/*
	CString str;
	for (int i = 0; i < 10; i++)
	{
		str.Format( "%d",i );
		m_sides.AddString( str );
	}
	*/


	return TRUE;  // return TRUE unless you set the focus to a control
}


void CVoxelObjectPanel::OnBnClicked()
{
	if (m_voxelObj)
	{
		SW_TEST_OBJ_MOD(m_voxelObj, false, false);

		SW_ON_OBJ_MOD(m_voxelObj);
		if(!m_voxelObj->ResetTransformation())
		{
			char out [1024];
			sprintf(out, 
				"Reset rotation operation is not possible on %s voxel object.", (const char*)m_voxelObj->GetName());
			MessageBox(out, "Reset rotation error", MB_OK|MB_ICONSTOP);
		}
		SW_ON_OBJ_MOD(m_voxelObj);
	}
  else
	{
		// Reset all selected voxels.
		CSelectionGroup *selection = GetIEditor()->GetSelection();

#ifdef SEG_WORLD
		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				SW_TEST_OBJ_MOD(pBaseObj, false, false);
			}
		}
#endif

		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				SW_ON_OBJ_MOD(pBaseObj);
				bool res = ((CVoxelObject*)pBaseObj)->ResetTransformation();
				SW_ON_OBJ_MOD(pBaseObj);
				if(!res)
				{
					char out [1024];
					sprintf(out, 
						"Reset rotation operation is not possible on %s voxel object.\n"
						"Press OK to continue processing other objects or press Cancel to abort.", (const char*)pBaseObj->GetName());
					if(MessageBox(out, "Reset rotation error", MB_OKCANCEL|MB_ICONSTOP)==IDCANCEL)
					{
						break;
					}
				}
			}
		}
	}
}

////////////////////////////////////////////////////////////
void CVoxelObjectPanel::OnBnSplit()
{
	if (m_voxelObj)
	{
		m_voxelObj->Split();
	}
	else
	{
		CSelectionGroup *selection = GetIEditor()->GetSelection();

#ifdef SEG_WORLD
		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				bool res = ((CVoxelObject*)pBaseObj)->SWCanSplit();
				if(!res)
					return;
			}
		}
#endif

		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				bool res = ((CVoxelObject*)pBaseObj)->Split();
				SW_ON_OBJ_MOD(pBaseObj);
			}
		}
	}
}

////////////////////////////////////////////////////////////
void CVoxelObjectPanel::OnUpdate()
{
	if (m_voxelObj)
	{
		SW_TEST_OBJ_MOD(m_voxelObj, false, true);

		m_voxelObj->Retriangulate();
		SW_ON_OBJ_MOD(m_voxelObj);
	}
	else
	{
		CSelectionGroup *selection = GetIEditor()->GetSelection();

#ifdef SEG_WORLD
		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				SW_TEST_OBJ_MOD(pBaseObj, false, false);
			}
		}
#endif

		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				((CVoxelObject*)pBaseObj)->Retriangulate();
				SW_ON_OBJ_MOD(pBaseObj);
			}
		}
	}
}

void CVoxelObjectPanel::OnCopyHM()
{
	if (m_voxelObj)
	{
		SW_TEST_OBJ_MOD(m_voxelObj, false, true);

		m_voxelObj->CopyHM();
		SW_ON_OBJ_MOD(m_voxelObj);
	}
	else
	{
		CSelectionGroup *selection = GetIEditor()->GetSelection();
		
#ifdef SEG_WORLD
		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				SW_TEST_OBJ_MOD(pBaseObj, false, true);
			}
		}
#endif

		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pBaseObj = selection->GetObject(i);
			if (pBaseObj->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
			{
				((CVoxelObject*)pBaseObj)->CopyHM();
				SW_ON_OBJ_MOD(pBaseObj);
			}
		}
	}
}


void CVoxelObjectPanel::OnSelectEmpty()
{
	GetIEditor()->ClearSelection();

	CBaseObjectsArray objects;
	GetIEditor()->GetObjectManager()->GetObjects( objects );
	for (int i = 0; i < objects.size(); i++)
	{
		CBaseObject *pObject = objects[i];
		if (pObject->IsKindOf(RUNTIME_CLASS(CVoxelObject)))
		{
			CVoxelObject * pVoxel = (CVoxelObject *) pObject;
			IVoxelObject * pRenderNode = (IVoxelObject *)pVoxel->GetEngineNode();
			if(pRenderNode && pRenderNode->IsEmpty())
			{
				GetIEditor()->SelectObject( pObject );
			}
		}
	}
}


void CVoxelObjectPanel::OnTerrainHole()
{
	if (m_voxelObj)
		m_voxelObj->MakeTerrainHole();
}